package com.gitee.wsl.func.filter.bloomfilter.predicate

import com.gitee.wsl.func.predicate.LongBiPredicate
import com.gitee.wsl.func.predicate.LongPredicate


/**
 * A long predicate that applies the test func to each member of the `ary` in sequence for each call to `test()`.
 * if the `ary` is exhausted, the subsequent calls to `test` are executed with a zero value.
 * If the calls to `test` do not exhaust the `ary` the `processRemaining` method can be called to
 * execute the @{code test} with a zero value for each remaining `idx` value.
 */
internal class CountingLongPredicate(
    private val ary: LongArray,
    private val func: LongBiPredicate
) : LongPredicate {
    private var idx = 0

    /**
     * Call the long-long consuming bi-predicate for each remaining unpaired long in
     * the input array. This method should be invoked after the predicate has been
     * passed to [com.gitee.wsl.func.filter.bloomfilter.api.BitMapExtractor.processBitMaps] to consume any
     * unpaired bitmaps. The second argument to the bi-predicate will be zero.
     *
     * @return true if all calls to the predicate were successful
     */
    fun processRemaining(): Boolean {
        // uses local references for optimization benefit.
        var i = idx
        val a = ary
        val limit = a.size
        while (i != limit && func.test(a[i], 0)) {
            i++
        }
        return i == limit
    }

     override fun test(t: Long): Boolean {
        return func.test(if (idx == ary.size) 0 else ary[idx++], t)
    }
}
